import requests
import json
import time
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor, as_completed # 导入 ThreadPoolExecutor 和 as_completed

# --- 配置信息 ---
BASE_URL = "http://69.231.135.101/pgktstudent/messageJW/send"
HEADERS = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "Authorization": "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImJiMDU1NDg4LTJiMzEtNGMwYi04YWU2LTg5ZTdmMTAxY2Y5ZSJ9.NmPhMk7K45JJXywXQImpo65H9PGIyDSMi5SI57FvZiqU5bxr18qS3Z6PII1IiqhLjRNSAFZclnnQ",
    # 替换为你的有效Authorization Token
    "Content-Type": "application/json",
    "Origin": "http://69.231.135.101",
    "Proxy-Connection": "keep-alive",
    "Referer": "http://69.231.135.101/pgktjwsnew/",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0",
}

# 视频的固定信息 (从你的请求中提取)
VIDEO_INFO = {
    "key": "d6F0EMViVeP9dUzcceYTsUhaqAQMndqvCsWHyeP/j/cVDfuamQ+2p3KR4l/Z1YG59C3eLtER2ZPMfP+Nsh2l4GDCW0Hci1rL5V1WEJYpfWCJelU/1XBhNIPrVGylzcyFMe1+l+MgBElzIGe7HvJdY2VC1UXG3oTixZ7jpFloZyYk6j1VC10NZUr1twb1z0jDl0QPoUYYy9y9AmDxv57gM7w==",
    "id": "0f4f0a742b974663944d3be692e38628",
}

# --- 模拟视频参数 ---
TOTAL_VIDEO_DURATION_SECONDS = 1872.8  # 视频总时长 (根据你之前日志中的 'pu' 字段的 playPosition 估算)
REPORT_INTERVAL_SECONDS = 120  # 每隔多少秒上报一次进度 (例如，每次上报进度增加120秒)
FLOAT_PRECISION = 6  # 浮点数精度，用于 playPosition 和 playRatio

# --- 循环控制参数 ---
NUM_SIMULATION_LOOPS = 20000 # 你希望模拟观看的次数
MAX_WORKERS = 10  # 最大线程数，可以根据你的网络和服务器性能调整

# --- 辅助函数 ---
def send_progress_request(position, ratio, status):
    """
    发送一个播放进度上报请求
    """
    data = {
        **VIDEO_INFO,  # 合并视频固定信息
        "playPosition": round(position, FLOAT_PRECISION),
        "playRatio": round(ratio, FLOAT_PRECISION),
        "playStatus": status
    }

    try:
        # verify=False 对应 curl 的 --insecure 选项，跳过SSL验证
        # 在多线程环境下，最好为每个线程使用独立的 requests.Session()，
        # 或者确保 requests 库的线程安全（requests 库本身是线程安全的，
        # 但会话对象 Session 应该谨慎共享）。这里由于是独立的POST请求，
        # 直接使用 requests.post 问题不大。
        response = requests.post(BASE_URL, headers=HEADERS, data=json.dumps(data), verify=False)
        response.raise_for_status()  # 如果状态码不是2xx，则抛出HTTPError
        return True # 请求成功
    except requests.exceptions.HTTPError as errh:
        print(f"HTTP Error: {errh}")
    except requests.exceptions.ConnectionError as errc:
        print(f"Error Connecting: {errc}")
    except requests.exceptions.Timeout as errt:
        print(f"Timeout Error: {errt}")
    except requests.exceptions.RequestException as err:
        print(f"Something went wrong: {err}")
    return False # 请求失败


# --- 主模拟逻辑 ---
def generate_watch_session_tasks():
    """
    生成一次完整的视频观看会话的所有请求参数。
    不实际发送请求，只返回一个列表，包含每个请求的 (position, ratio, status) 元组。
    """
    tasks = []
    current_position = 0.0

    # 1. 初始状态：waiting (playPosition=0)
    tasks.append((0, 0, "waiting"))

    # 2. 逐步生成 playing 状态的请求
    while current_position < TOTAL_VIDEO_DURATION_SECONDS:
        current_position += REPORT_INTERVAL_SECONDS

        # 确保不会超出视频总时长
        if current_position > TOTAL_VIDEO_DURATION_SECONDS:
            current_position = TOTAL_VIDEO_DURATION_SECONDS

        current_ratio = current_position / TOTAL_VIDEO_DURATION_SECONDS

        tasks.append((current_position, current_ratio, "playing"))

        # 如果达到了视频结尾，就停止生成
        if current_position == TOTAL_VIDEO_DURATION_SECONDS:
            break

    # 3. 结束状态 (可选，但推荐)
    tasks.append((TOTAL_VIDEO_DURATION_SECONDS, 1.0, "ended"))
    return tasks

def simulate_single_watch_session():
    """
    模拟一次完整的视频观看会话（从开始到结束）。
    此函数现在只负责生成任务，而不执行它们。
    """
    # 这里的 sleep 是为了模拟用户在开始新的观看会话前有一定的间隔
    # 在多线程环境下，如果这个 sleep 是在线程内部执行，会阻塞该线程
    # 如果希望模拟不同时间的用户，这个 sleep 可以在主线程循环中保留
    # time.sleep(1) # 这个 sleep 移到 main 函数的外层循环
    return generate_watch_session_tasks()


def main():
    """
    主函数，控制循环模拟观看。
    """
    print(f"准备开始模拟视频观看，共循环 {NUM_SIMULATION_LOOPS} 次。")
    print(f"每个视频会话总时长: {TOTAL_VIDEO_DURATION_SECONDS} 秒，每 {REPORT_INTERVAL_SECONDS} 秒上报一次进度。")
    print(f"将使用 {MAX_WORKERS} 个线程并行处理请求。")
    print("---")

    all_tasks_to_submit = []
    for _ in range(NUM_SIMULATION_LOOPS):
        session_tasks = simulate_single_watch_session()
        all_tasks_to_submit.extend(session_tasks)

    print(f"总计需要发送 {len(all_tasks_to_submit)} 个请求。")

    # 使用 ThreadPoolExecutor 来并行发送请求
    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        # submit 方法提交任务，并返回一个 Future 对象
        futures = [executor.submit(send_progress_request, pos, ratio, status)
                   for pos, ratio, status in all_tasks_to_submit]

        # 使用 tqdm 包装 as_completed 来显示进度条
        # as_completed 会在任务完成时按顺序返回它们的 Future 对象
        for future in tqdm(as_completed(futures), total=len(futures), desc="整体进度", unit="请求"):
            # 可以选择在这里处理每个任务的结果（成功或失败）
            result = future.result()
            if not result:
                # 实际应用中可能需要更详细的错误处理和日志记录
                pass

    print("\n所有视频观看模拟已完成。")


if __name__ == "__main__":
    main()